import { Button, Divider, Space, Typography } from 'antd';
import { create, StoreApi, UseBoundStore } from 'zustand';

type WithSelectors<S> = S extends { getState: () => infer T }
	? S & { use: { [K in keyof T]: () => T[K] } }
	: never;

const createSelectors = <S extends UseBoundStore<StoreApi<object>>>(_store: S) => {
	const store = _store as WithSelectors<typeof _store>;
	store.use = {};
	for (const k of Object.keys(store.getState())) {
		(store.use as any)[k] = () => store((s) => s[k as keyof typeof s]);
	}

	return store;
};

interface BearState {
	bears: number;
	name: string;
	increase: (by: number) => void;
	increment: () => void;
}

const useBearStoreBase = create<BearState>()((set) => ({
	bears: 0,
	name: 'frank',
	increase: (by) => set((state) => ({ bears: state.bears + by })),
	increment: () => set((state) => ({ bears: state.bears + 1 }))
}));

const useBearStore = createSelectors(useBearStoreBase);

const Selector = () => {
	const bears = useBearStore.use.bears();
	const increment = useBearStore.use.increment();
	const increase = useBearStore.use.increase();

	const store = useBearStoreBase((state) => Object.keys(state));
	console.log(store);

	return (
		<>
			<Typography.Title>Auto Generating Selectors</Typography.Title>
			<Divider />
			<Typography.Text>{store.join(', ')}</Typography.Text>
			<Divider />
			<Space>
				<Button type="primary" onClick={() => increment()}>
					bears: {bears}
				</Button>
				<Button ghost type="primary" onClick={() => increase(3)}>
					increase
				</Button>
				<Button type="primary" hidden={false}>
					hidden
				</Button>
			</Space>
		</>
	);
};

export default Selector;
